feat(payments): Add LangGraph integration for payment handling - #546
Merged
Conversation
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 18:03 — with
GitHub Actions
Failure
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 18:03 — with
GitHub Actions
Failure
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 18:03 — with
GitHub Actions
Failure
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 18:03 — with
GitHub Actions
Failure
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 18:03 — with
GitHub Actions
Failure
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 18:03 — with
GitHub Actions
Failure
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 18:03 — with
GitHub Actions
Failure
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 18:03 — with
GitHub Actions
Failure
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 18:03 — with
GitHub Actions
Failure
rajuans
reviewed
Jun 23, 2026
rajuans
reviewed
Jun 23, 2026
rajuans
reviewed
Jun 23, 2026
Merge AgentCorePaymentsConfig (LangGraph) and AgentCorePaymentsPluginConfig (Strands) into a single dataclass in integrations/config.py. Both names remain available as aliases for backward compatibility.
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 21:54 — with
GitHub Actions
Failure
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 21:54 — with
GitHub Actions
Failure
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 21:54 — with
GitHub Actions
Failure
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 21:54 — with
GitHub Actions
Failure
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 21:54 — with
GitHub Actions
Failure
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 21:54 — with
GitHub Actions
Failure
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 21:54 — with
GitHub Actions
Failure
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 21:54 — with
GitHub Actions
Failure
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 21:54 — with
GitHub Actions
Failure
… of in langgraph-specific package
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 21:56 — with
GitHub Actions
Failure
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 21:56 — with
GitHub Actions
Failure
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 21:56 — with
GitHub Actions
Failure
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 21:56 — with
GitHub Actions
Failure
ragsu43
had a problem deploying
to
manual-approval
June 23, 2026 21:56 — with
GitHub Actions
Failure
…cation Extract guard checks, 402 detection, payment request extraction, header injection, and post-payment rejection detection into shared private methods. The sync and async paths now only differ at await/sleep boundaries. Future bug fixes to detection or injection logic only need to be applied in one place instead of four. No behavioral changes — 128 tests pass identically before and after.
ragsu43
force-pushed
the
ragsu/langgraph-integration
branch
from
July 2, 2026 01:52
17b79dc to
b44cf37
Compare
Document when each path is used (.invoke vs .ainvoke), what the async path does differently (non-blocking sleep, to_thread for signing, async callbacks), and provide FastAPI and script examples.
aidandaly24
requested changes
Jul 6, 2026
aidandaly24
left a comment
Contributor
There was a problem hiding this comment.
Nice work on this. The overall flow (detect, sign, inject, retry, across sync and async, plus the recovery callback and auto-session) reads well and the unit coverage is thorough. Requesting changes on a couple of correctness issues before this goes in, plus some cleanup.
Blocking:
- Sync path silently drops async
on_payment_errorcallbacks (middleware.py:555). _check_post_recovery_rejectionsurfaces the wrong error detail because it never swaps in the fallback handler (middleware.py:373).
Should fix:
- Detection ignores the name-based handler registry, so legacy text-format 402s get missed (middleware.py:267).
- The exported
MCPRequestPaymentHandlercan't actually be used as acustom_handlersentry because of a shape mismatch (middleware.py:269).
Cleanup:
- The sync/async and the two rejection-check methods are near-duplicates and have already drifted, worth collapsing (middleware.py:353).
- Move the inline imports up to the top of the file per our style (middleware.py, several spots).
One process note: the header on test_functional.py says any change to this middleware has to be validated against a live Base Sepolia testnet before merge. Please confirm that run has happened.
If an async def on_payment_error callback is registered but the agent runs via .invoke() (sync path), the callback would silently return an unawaited coroutine, bypass RETRY logic, and leak a RuntimeWarning. Now we detect this with inspect.iscoroutinefunction() and raise a clear TypeError that the existing try/except catches and logs — the agent continues with the default error message and the developer sees exactly what to fix in their logs.
…path Verify that when a raw-JSON tool returns 402 after error handler recovery, the FallbackHandler is used to extract the real error detail (e.g. 'budget exceeded') instead of falling through to 'unknown'.
When fallback detects a 402 in the recovery retry path, reassign _rh to _FallbackHandler(fallback) so extract_body returns the actual parsed body. Without this, GenericPaymentHandler looks for the PAYMENT_REQUIRED marker, finds nothing in raw JSON, and the LLM sees 'unknown' instead of the real error detail.
When both GenericPaymentHandler (marker) and _fallback_detect_402 (JSON) fail to detect a 402, try the name-based handler from get_payment_handler (e.g. HttpRequestPaymentHandler for tools named http_request). This covers the legacy 'Status Code: 402' text-block format used by Strands tools ported to LangGraph without format adaptation.
…hape
Custom handlers now receive result.content (the raw ToolMessage content)
for extract_status_code, extract_headers, and extract_body — not the
internal {'content': [{'text': ...}]} prepared shape.
This makes the custom handler contract intuitive: handlers parse the
tool's actual output format, not a middleware-internal wrapper. Fixes
silent detection failures when custom handlers expected raw JSON or
other native formats.
Add tests for: - Async auto_session creation and reuse - Async post-payment rejection with raw JSON fallback - Async name-based handler fallback (legacy text-block format) - Async custom handler receiving raw content - Async error handler callback (retry and propagate paths) - Sync custom handler raw content contract verification Suite now at 141 passed, providing async path parity with sync tests.
- Merge _check_post_payment_rejection and _check_post_recovery_rejection into single _check_retry_rejection with context parameter - Extract _inject_for_error_retry for shared injection in error handlers - Extract _build_error_context for shared PaymentErrorContext construction - Extract _handle_callback_resolution for shared resolution dispatch Reduces middleware.py from 805 to 704 lines. The sync/async error handlers now only differ at await/sleep/to_thread boundaries. 141 tests pass identically.
Move asyncio, json, GenericPaymentHandler, ErrorResolution, and PaymentErrorContext imports to the top of the file. None have circular dependency risks. Eliminates repeated imports that contributed to drift between duplicated code blocks.
… contract Update TrackingHandler and RawJsonHandler in test_functional.py to handle raw content (str/list) instead of the prepared shape dict. Required after the custom handler contract change in 076d6ed.
aidandaly24
approved these changes
Jul 7, 2026
aidandaly24
left a comment
Contributor
There was a problem hiding this comment.
Thanks for making the fixes, approved.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description of changes:
Added LangGraph middleware and config files for developer integration with ACP.